<?php
/**
 * Created by PhpStorm.
 * User: zlkmu
 * Date: 2017/10/4
 * Time: 22:30
 * 用于麻将的房间类
 * 继承自Room
 * 继承属性
 *   protected $roomID;        //房间ID
     protected $roomDBID;      //房间数据库ID
     protected $roomType;      //房间类型, 参考ServerContext的RoomType
     protected $playerList;    //玩家队列，每个类型是一个Player

     protected $isBegin;       //是否开始
     protected $disolveCount = 1; //同意解散房间人数数量
     protected $refuseDisolve = 0; //拒绝解散房间人数数量
     protected $isDissolve;       //是否解散房间

     protected $totalCount;       //房间总盘数
     protected $currentRount;     //当前盘数
 */
    require_once __DIR__.'/../Room.php';
    require_once ('MajongManager.php');
    require_once ('MajangPlayer.php');
    require_once ('MajangContext.php');
    require_once ('MaJangRoomRecorder.php');
    require_once ('MajangProcessor.php');
    require_once __DIR__.'/../../Server/ServerContext.php';
    class MaJangRoom extends Room {
        //麻将房间需要保存的基本数据
        //如是否推牌，是否红5,等等

        //麻将牌堆
        private $majongManager;
        //庄ID
        private $currentZhuang;
        //创建者ID
        private $roomCreator;

        //房间进行过程中的记录器
        private $roomRecorder;



        //某一次玩家打牌后的，其它玩家的可能结果组合
        //array(i=>array('from'=>哪个玩家打的,'to'=>当前判断的是哪个玩家, 'peng'=>能否碰，'gang'=>能否杠, 'hu'=>能否胡))
        private $playerDaPaiResult = array();

        //某一次玩家摸牌后的结果
        //array('playerID'=>array('hu'=>true/false, 'gang'=> MING_GANG/AN_GANG/false, 'ting'=>array(i=>array(打什么牌, array(胡的牌))))
        private $playerMoPaiResult = array();

        //某一次玩家打牌后，其它玩家的选择结果，用于判断碰，杠，胡冲突的情况
        //array(playerID, dicision:0,过，1碰，2杠，3胡)
        private $playerDecision = array();




        /**
         * 玩家胡牌的函数
         * @param $playerID 胡牌的玩家ID
         * @param $pai 胡的哪张牌
         * @return 胡牌翻数或0：不能胡
         */
        function playerHu($playerID, $pai){

            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    $r = $this->playerList[$i]->huPai($pai);
                    $this->roomRecorder->recordPlayerDecision($playerID, PLAYER_HUPAI);
            //        array_push($this->playerDecision, array('playerID'=>$playerID, 'dicision'=>PLAYER_HUPAI));
                    return $r;
                }
            }
            return false;
        }

        /**
         * 这是一个测试函数
         * @param $playerID
         * @param $pai
         */
        function setPlayerPai($playerID, $pai){
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    $this->playerList[$i]->setPai($pai);
                }
            }
        }


        /**
         * 获取玩家牌型的函数
         * @param $playerID
         * @return mixed
         */
        function getPlayerPai($playerID){
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    return $this->playerList[$i]->getPai();
                }
            }
            return DATA_ERROR;
        }

        /**
         * 加入房间
         * @param $playerID 玩家ID
         */
        function joinRoom($playerID){
            array_push($this->playerList, new MajangPlayer($playerID));
        }

        /**
         * 离开房间
         * @param $playerID 玩家ID
         */
        function leftRoom($playerID){
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    array_splice($this->playerList, $i, 1);
                    break;
                }
            }
        }

        /**
         * 构造函数，传入房间参数
         * @param $roomRequest，前台传入的房间参数，房间创建者是谁
         */
        function __construct($roomRequest, $createPlayer)
        {
            //初始化所有参数
            $this->isBegin = false;
            $this->majongManager = new MajongManager();
            $this->serverContext = new ServerContext();
            $this->roomCreator = $createPlayer;

            $this->roomRecorder = new MaJangRoomRecorder();
        }

        /**
         * 获取玩家在房间位置的函数，默认庄为1，其它玩家按照以下排列
         *    3
         * 4     2
         *    1
         *
         * @return int
         */
        private function getPlayerPos(){
            $tempPos = 0;
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $this->currentZhuang){
                    $tempPos = $i + 1;
                    break;
                }
            }
            if(($tempPos == count($this->playerList)) && (count($this->playerList) == 3)){
                $tempPos++;
            }
            return $tempPos;
        }

        /**
         * 处理玩家准备请求的函数
         * @param $playerID
         * @return $notReadyPlayer array('playerID');
         */
        function playerReady($playerID){
            $notReadyPlayer = array();
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    $this->playerList[$i]->readyForPlay();
                }
                else{
                    array_push($notReadyPlayer, $this->playerList[$i]->getPlayerID());
                }
            }
            //发送信息给没有准备的玩家
            return $notReadyPlayer;
        }

        /**
         * 开始某一局游戏，返回骰子和发的牌
         * @return array: {'zhuang'=>当前庄的playerID},{'touzi'=>{骰子1， 骰子2}, 'fapai'=>{'playerID1'=>牌, 'playerID2'=>牌,...}}
         */
        function beginGame(){

            //返回结果
            $returnResult = array();
            if($this->currentRound == 0){
                //当第一局的时候，初始化MajangRoomRecorder
                $this->roomRecorder->initRecorder($this->playerList);
                $this->randFirstZhuang();
            }
            $this->currentRound++;
            $this->majongManager->createMajong();
            $touzi = $this->majongManager->startTouzi($this->getPlayerPos());

            $tempPlayerList = array();
            array_push($tempPlayerList, $this->currentZhuang);
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() != $this->currentZhuang){
                    array_push($tempPlayerList, $this->playerList[$i]->getPlayerID());
                }
            }
            //起牌函数，这个函数只返回一人13张牌
            $fapaiResult = $this->majongManager->qiPai($tempPlayerList);
            //设置每个玩家的牌
            for($i = 0; $i < count($this->playerList); $i++){
                for($j = 0; $j < count($fapaiResult); $j++){
                    if($this->playerList[$i]->getPlayerID() == $fapaiResult[$j]['playerID']){
                        $this->playerList[$i]->setPai($fapaiResult[$j]['pai']);
                    }
                }
            }
            $returnResult['zhuang'] = $this->currentZhuang;

            $returnResult['touZi'] = $touzi;
            $returnResult['faPai'] = $fapaiResult;

           // print_r($fapaiResult);
            return $returnResult;
        }

        /**
         * 第一盘开始的时候，选庄
         * 存入属性currentZhuang
         */
        private function randFirstZhuang(){
            $id = mt_rand(0, count($this->playerList) - 1);
            $this->currentZhuang = $this->playerList[$id]->getPlayerID();
        }

        /**
         * 某个玩家摸牌，
         * @param $playerID 某个玩家摸牌
         * @return array(pai, array('hu'=>true/false, 'gang'=>true/false, 'ting'=>array(i=>array(打的牌, array(能胡的牌)))
         */
        function moPai($playerID){
            $pai = $this->majongManager->moPai();
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    $r = $this->playerList[$i]->moPai($pai);
                    $this->roomRecorder->recordMoPaiResult($playerID, $r);
                    break;
                }
            }
            return array($pai, $r);
        }


        function testMoPai($playerID, $pai){

            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    $r = $this->playerList[$i]->moPai($pai);
                    $this->roomRecorder->recordMoPaiResult($playerID, $r);
                    break;
                }
            }
            return array($pai, $r);
        }


        /**
         * 某个玩家打牌的函数
         * @param $playerID 玩家ID
         * @param $pai 打的具体牌
         */
        function playerDaPai($playerID, $pai){

            for($i = 0; $i < count($this->playerList); $i++){
                  if($this->playerList[$i]->getPlayerID() == $playerID){
                      $r = $this->playerList[$i]->daPai($pai);
                      break;
                  }
            }

            //玩家打牌成功
            if($r){
                //检查其它玩家对打出来的牌的计算结果,进行保存
                $r = $this->checkPlayerDaPaiResult($playerID, $pai);
                $this->roomRecorder->recordDaPaiResult($playerID, $r);
                MajangProcessor::PlayerDaPai($r);
                //return  $this->playerDaPaiResult;
            }

        }

        function playerGuoPai($playerID){
            $this->roomRecorder->recordPlayerDecision($playerID, PLAYER_GUOPAI);
           // array_push($this->playerDecision, array('playerID'=>$playerID, 'decision'=>PLAYER_GUOPAI));
        }

        /**
         * 检查当某个玩家打出某张牌后，房间内其它玩家的反应
         * @param $playerID 打牌的玩家
         * @param $pai 打出来的牌
         * @return array(i=>array('from'=>哪个玩家打的,'to'=>当前判断的是哪个玩家, 'peng'=>能否碰，'gang'=>能否杠, 'hu'=>能否胡))
         */
        private function checkPlayerDaPaiResult($playerID, $pai){
            $result = array(/*'from'=>$playerID, 'to'=>'', 'peng'=>'', 'gang'=>'', 'hu'=>array()*/);
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() != $playerID){
                    array_push($result,
                        array('from'=>$playerID,
                              'to'=>$this->playerList[$i]->getPlayerID(),
                              'peng'=>$this->playerList[$i]->checkPeng($pai),
                              'gang'=>$this->playerList[$i]->checkGang($pai),
                              'hu'=>$this->playerList[$i]->checkHu($pai)));
                }
            }

            return $result;
        }

        /**
         * 房间中的某个玩家碰牌
         * @param $playerID 玩家ID
         * @param $pai 牌型
         * @return int 52不能碰，有玩家胡， 51还要等带其它玩家响应, 50数据错误, PAI型
         */
        function playerPengPai($playerID, $pai){
            $r = $this->roomRecorder->canPlayerPengOrGang($playerID);
            //echo $r;
            if($r != CAN_PENG_OR_GANG){
                return $r;
            }

            for($i = 0; $i < count($this->playerList); $i++){
                if($playerID == $this->playerList[$i]->getPlayerID()){
                    return $this->playerList[$i]->pengPai($pai);
                }
            }
            return DATA_ERROR;
        }

        /**
         * 某位玩家杠牌的函数
         * @param $playerID
         * @param $pai
         * @return int
         */
        function playerGangPai($playerID, $pai){
            $r = $this->roomRecorder->canPlayerPengOrGang($playerID);
            if($r != CAN_PENG_OR_GANG){
                return $r;
            }

            for($i = 0; $i < count($this->playerList); $i++){
                if($playerID == $this->playerList[$i]->getPlayerID()){
                    //玩家杠牌，然后摸一张牌
                    $r = $this->playerList[$i]->gangPai($pai);
                    if($r == DATA_ERROR){
                        return $r;
                    }
                    else{
                        //记录结果
                    }
                    //玩家应该摸一张牌
                    $moPaiResult = $this->moPai($this->playerList[$i]->getPlayerID());

                }
            }
            return DATA_ERROR;
        }

        /**
         * 检查某个玩家摸排后，自己的结果
         */
        function checkPlayerMoPaiResult($playerID, $pai){

        }

        /**
         * @param $playerID
         * @return bool
         */
        private function isPlayerInRoom($playerID){
            for($i = 0; $i < count($this->playerList); $i++){
                if($this->playerList[$i]->getPlayerID() == $playerID){
                    return true;
                }
            }
            return false;
        }

        /**
         * 玩家推牌的函数
         * @param $playerID 推牌玩家的ID,这里是测试版本，所以直接用的玩家对象
         * @param $tuiRequest 推的牌，这里需要前台发过来的数据为:tuiPai=>逗号分隔的牌型，具体推的牌, 推的牌就用1-9， 11-19， 21-29确定
         *                                                    tingPai=>听的牌,逗号分隔的牌型
         * @return
         */
        function playerTuiPai($player, $playerID, $tuiRequest){
            if(array_key_exists($playerID, $this->tuiArray)){
                return false;
            }
            array_push($this->tuiArray, array($playerID=>array($tuiRequest['tuiPai'], $tuiRequest['tingPai'])));
        }








    }


?>